package com.yuyou.fn.common.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.common.entity.Sms;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.mapper.SmsMapper;
import com.yuyou.fn.common.service.ISiteConfigService;
import com.yuyou.fn.common.service.ISmsService;
import com.yuyou.fn.common.util.CriteriaUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.common.vo.SmsQueryVo;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Sms 表数据服务层接口实现类
 */
@Service
public class SmsServiceImpl extends SuperServiceImpl<SmsMapper, Sms, Long> implements ISmsService {

    @Resource
    private ISiteConfigService siteConfigService;

    @Value("${dev.env}")
    private boolean dev;

    private static final String route="/api/message/sendSMSByNos";

    OkHttpClient client = new OkHttpClient.Builder().retryOnConnectionFailure(true).connectTimeout(60, TimeUnit.SECONDS ).readTimeout(10,TimeUnit.SECONDS).build();

    @Override
    public boolean sendCode(String phoneNo) {
        Example<Sms> smsExample = Sms.createExample();
        Example.Criteria criteria = smsExample.createCriteria();
        criteria.andEqualTo("smsType", 1).andEqualTo("phoneNo", phoneNo);
        smsExample.orderBy("createTime").desc();
        Sms sms = findOneByExample(smsExample);

        if (sms == null || (new Date().getTime() - sms.getCreateTime().getTime()) > 1 * 60 * 1000) {
            try {

                String code = "999999";

                int sendResult = 0;
                if (!dev) {
                    code = RandomStringUtils.randomNumeric(6);
                    String content = String.format("您的验证码为：%s，此验证码有效时长为30分钟，如非本人操作，请忽略此短信。", code);

                    String url  =  siteConfigService.findConfigValue("yyfn_message")+route;
                    String token=siteConfigService.findConfigValue("yyfn_message_token");
                    Map<String,String> params = new HashMap<>();
                    params.put("phoneNos" ,phoneNo);
                    params.put("content" ,content );
                    params.put("token", DigestUtils.md5Hex(phoneNo+token));
                    FormBody.Builder formBody = new FormBody.Builder();
                    for(Map.Entry<String,String> entry : params.entrySet() ){
                        formBody.add(entry.getKey(),entry.getValue());
                    }
                    Request request = new Request.Builder().url(url).post(formBody.build()).build() ;
                    Response response = client.newCall(request).execute();
                    if (response.code()!=200){
                        throw new BusException("网络错误");
                    }
                    String result=response.body().string() ;
                    JSONObject jsonObject=JSONObject.parseObject(result);
                    int resultCode=jsonObject.getIntValue("resultCode");

                    sendResult=resultCode;

                }
                Sms nSms = new Sms();
                nSms.setContent(code);
                nSms.setSmsType(1);
                nSms.setPhoneNo(phoneNo);
                Date now = new Date();
                nSms.setCreateTime(now);
                nSms.setUpdateTime(now);
                nSms.setResultCode(sendResult);
                insert(nSms);
                if (sendResult != 0) {
                    return false;
                }


            } catch (Exception e) {
                throw new RuntimeException("sms not available", e);
            }
        }

        return true;
    }

    @Override
    public boolean validate(String phoneNo, String code) {

        if (dev) {
            return true;
        }

        Example<Sms> smsExample = Sms.createExample();
        Example.Criteria criteria = smsExample.createCriteria();
        criteria.andEqualTo("smsType", 1).andEqualTo("phoneNo", phoneNo).andEqualTo("content", code);
        smsExample.orderBy("createTime").desc();
        Sms sms = findOneByExample(smsExample);
        if (sms == null || (new Date().getTime() - sms.getCreateTime().getTime()) > 30 * 60 * 1000) {
            return false;
        }

        return true;
    }

    @Override
    public boolean send(List<String> phoneNoList, String msg) throws Exception {

        int sendResult = 0;
        try {
            if (!dev) {
                String url  =  siteConfigService.findConfigValue("yyfn_message")+route;
                String token=siteConfigService.findConfigValue("yyfn_message_token");
                Map<String,String> params = new HashMap<>();
                String phoneNos= StringUtils.join(phoneNoList,",");
                params.put("phoneNos" ,phoneNos);
                params.put("content" ,msg );
                params.put("token", DigestUtils.md5Hex(phoneNos+token));
                FormBody.Builder formBody = new FormBody.Builder();
                for(Map.Entry<String,String> entry : params.entrySet() ){
                    formBody.add(entry.getKey(),entry.getValue());
                }
                Request request = new Request.Builder().url(url).post(formBody.build()).build() ;
                Response response = client.newCall(request).execute();
                if (response.code()!=200){
                    throw new BusException("网络错误");
                }
                String result=response.body().string() ;
                JSONObject jsonObject=JSONObject.parseObject(result);
                int resultCode=jsonObject.getIntValue("resultCode");

                sendResult=resultCode;


            }
            List<Sms> smsList = new ArrayList<>(phoneNoList.size());

            Date now = new Date();
            for (String p : phoneNoList) {
                Sms nSms = new Sms();
                nSms.setContent(msg);
                nSms.setSmsType(2);
                nSms.setPhoneNo(p);
                nSms.setCreateTime(now);
                nSms.setUpdateTime(now);
                nSms.setResultCode(sendResult);
                smsList.add(nSms);
            }
            insertBatch(smsList);
            if (sendResult != 0) {

                return false;
            }
        }catch (Exception e){
            throw new RuntimeException("sms not available", e);
        }

        return true;
    }

    @Override
    public List<Sms> findSmsCodeList(SmsQueryVo smsQueryVo) {
        Example<Sms> example=Sms.createExample();
        Example.Criteria criteria=example.createCriteria();
        CriteriaUtils.fillCondition(criteria,smsQueryVo);
        criteria.andEqualTo("smsType",1);
        example.orderBy("createTime").desc();
        return this.findListByExample(example);
    }

    @Override
    public Page<Sms> findSmsCodePage(SmsQueryVo smsQueryVo, int pageNo, int pageSize) {
        if (smsQueryVo.getEndDate()!=null){
            smsQueryVo.setEndDate(TimeUtils.changeOneDateLastTime(smsQueryVo.getEndDate()));
        }
        Example<Sms> example=Sms.createExample();
        Example.Criteria criteria=example.createCriteria();
        CriteriaUtils.fillCondition(criteria,smsQueryVo);
        criteria.andEqualTo("smsType",1);
        example.orderBy("createTime").desc();
        return this.findPageByExample(example,pageNo,pageSize);
    }
}